#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <pcap.h>
#include <openssl/ssl.h>
#include <netinet/in.h>
#include <iostream>

void packet_handler(u_char *user, const struct pcap_pkthdr *header, const u_char *packet)
{
    SSL *ssl;
    const u_char *payload;
    int payload_len;
    printf("==========%x %x %d\n", packet[36], packet[37], header->len);
    // 假设SMTPS的目标端口是465
    if (packet[36] == 0x01 && packet[37] == 0xd1) {
        // SSL/TLS握手开始于第5个TCP分段，也就是第54个字节
        payload = packet + 54;
        payload_len = header->len - 54;

        printf("%.*s\n", payload_len, payload);
        // 创建SSL对象并解密数据包中的SSL/TLS数据
        std::cout << "1111" << std::endl;
        ssl = SSL_new(NULL);
        std::cout << "22" << *(int *)user << std::endl;
        SSL_set_fd(ssl, *(int *)user);
        std::cout << "33" << std::endl;
        SSL_read(ssl, (char *)payload, payload_len);
        std::cout << "44" << std::endl;
        SSL_free(ssl);
        std::cout << "55" << std::endl;

        // 处理SMTPS数据流
        printf("%.*s\n", payload_len, payload);
    }
}

void getAllIface()
{
    char errbuf[PCAP_ERRBUF_SIZE]; // 错误信息缓冲区
    pcap_if_t *interface_list; // 接口列表

    // 调用pcap_findalldevs函数查找所有可用的网络接口
    if (pcap_findalldevs(&interface_list, errbuf) == -1) {
        fprintf(stderr, "Error finding available interfaces: %s\n", errbuf);
        exit(1);
    }

    // 遍历接口列表，并打印每个接口的名称和描述信息
    for (pcap_if_t *iface = interface_list; iface != NULL; iface = iface->next) {
        printf("Interface name: %s\n", iface->name);
        printf("Interface description: %s\n\n", iface->description);
    }

    // 释放接口列表的内存
    pcap_freealldevs(interface_list);
}

int main(int argc, char *argv[])
{
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *handle;
    struct bpf_program fp;
    bpf_u_int32 mask, net;
    int socket;
    getAllIface();
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <iface>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // 打开网卡接口
    handle = pcap_open_live(argv[1], BUFSIZ, 1, 1000, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", argv[1], errbuf);
        exit(EXIT_FAILURE);
    }

    // 获取本地IP地址和子网掩码
    if (pcap_lookupnet(argv[1], &net, &mask, errbuf) == -1) {
        fprintf(stderr, "Couldn't get netmask for device %s: %s\n", argv[1], errbuf);
        net = 0;
        mask = 0;
    }

    // 过滤SMTPS流量
    if (pcap_compile(handle, &fp, "tcp dst port 465", 0, net) == -1) {
        fprintf(stderr, "Couldn't parse filter: %s\n", pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter: %s\n", pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }

    // 创建TCP套接字并绑定到本地端口
    socket = ::socket(AF_INET, SOCK_STREAM, 0);
    bind(socket, NULL, sizeof(struct sockaddr_in));

    // 开始抓取数据包并处理
    pcap_loop(handle, -1, packet_handler, (u_char *)&socket);

    // 关闭网络接口和TCP套接字
    pcap_close(handle);
    close(socket);

    return 0;
}
